home *** CD-ROM | disk | FTP | other *** search
/ Aminet 6 / Aminet 6 - June 1995.iso / Aminet / util / cdity / Select.lha / Select / Source / Select.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-04-04  |  29.0 KB  |  1,261 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <devices/timer.h>
  5. #include <dos/dos.h>
  6. #include <exec/lists.h>
  7. #include <exec/memory.h>
  8. #include <exec/nodes.h>
  9. #include <intuition/gadgetclass.h>
  10. #include <intuition/intuitionbase.h>
  11. #include <workbench/workbench.h>
  12. #include <workbench/startup.h>
  13. #include <proto/commodities.h>
  14. #include <proto/dos.h>
  15. #include <proto/exec.h>
  16. #include <proto/gadtools.h>
  17. #include <proto/graphics.h>
  18. #include <proto/icon.h>
  19. #include <proto/intuition.h>
  20.  
  21. /************************************************************/
  22. /***  Program: Select                                     ***/
  23. /***  Version: 1.01                                       ***/
  24. /***   Author: Torsten Kramer                             ***/
  25. /***                                                      ***/
  26. /***  Copyright 1995 by Torsten Kramer                    ***/
  27. /***                                                      ***/
  28. /***  Version history:                                    ***/
  29. /***  0.01  - 19.12.1994: 1. Testversion                  ***/
  30. /***  0.02  - 17.01.1995: Aktualisierung durch Timer raus ***/
  31. /***  1.00  - 19.01.1995: 1. Release                      ***/
  32. /***  1.01  - 21.03.1995: Aktualisierung durch Timer rein ***/
  33. /***                      ESC wird unterstützt            ***/
  34. /***                      Option PUBSCREEN eingebaut      ***/
  35. /************************************************************/
  36.  
  37. #define PROG_NAME            "Select"
  38. #define PROG_VERSION    "1.01"
  39. #define PROG_DATE            "21.03.95"
  40. #define PROG_DESCR        "Helps to handle screens and windows"
  41.  
  42. #define DEF_HOTKEY        "ctrl alt s"
  43. #define DEF_PUBSCREEN    "Workbench"
  44.  
  45. #define TEMPLATE    "CX_POPUP/K,CX_POPKEY/K,CX_PRIORITY/N/K,PUBSCREEN/K"
  46. #define OPT_POPUP            0
  47. #define OPT_HOTKEY        1
  48. #define OPT_PRIORITY    2
  49. #define OPT_PUBSCREEN    3
  50. #define NUM_OPTS            4
  51.  
  52. #define WIN_IDCMP        IDCMP_VANILLAKEY | IDCMP_RAWKEY | IDCMP_REFRESHWINDOW | \
  53.                                         IDCMP_CLOSEWINDOW | IDCMP_MENUPICK | LISTVIEWIDCMP
  54.  
  55. #define ID_LISTVIEW    0
  56.  
  57. #define MENU_PROJECT    0
  58. #define ITEM_NEWSHELL    0
  59. #define ITEM_HIDE            1
  60. #define ITEM_ABOUT        2
  61. #define ITEM_QUIT            4
  62.  
  63. #define PRI_WINDOWS                1
  64. #define PRI_TITLE_WINDOWS    2
  65. #define PRI_SCREENS                3
  66. #define PRI_TITLE_SCREENS    4
  67.  
  68. #define EVT_HOTKEY 1L
  69.  
  70. #define    ESC                    0x1b
  71. #define CURSOR_UP        0x4c
  72. #define CURSOR_DOWN    0x4d
  73. #define ENTER                0x0d
  74.  
  75. #define max(a,b) ((a)>(b)?(a):(b))
  76.  
  77. /**********************************************************/
  78. /*  Prototypes                                            */
  79. /**********************************************************/
  80.  
  81. BOOL open_libs(void);
  82. void close_libs(void);
  83. BOOL read_args(int, char **);
  84. BOOL open_device(void);
  85. void close_device(void);
  86. BOOL setup_cx(void);
  87. void free_cx(void);
  88. BOOL open_interface(void);
  89. void close_interface(void);
  90. BOOL gadgets(void);
  91. BOOL menu(void);
  92. void refresh_listview(void);
  93. BOOL create_item_list(void);
  94. void free_nodes(void);
  95. void newshell(void);
  96. void timer(void);
  97. void click_to_front(UWORD);
  98. void select_label(void);
  99. void about(void);
  100. void process_msg(void);
  101.  
  102. /**********************************************************/
  103. /*  Structures                                            */
  104. /**********************************************************/
  105.  
  106. struct NewGadget    ng;
  107.  
  108. struct NewMenu        NewMenu[] =
  109. {
  110.     {NM_TITLE,    "Project",        0        , 0, 0, 0},
  111.     {NM_ITEM,        "Newshell",        "N"    , 0, 0, 0},
  112.     {NM_ITEM,        "Hide",                "H"    , 0, 0, 0},
  113.     {NM_ITEM,        "About...",        "A"    , 0, 0, 0},
  114.     {NM_ITEM,        NM_BARLABEL,    0        , 0, 0, 0},
  115.     {NM_ITEM,        "Quit",                "Q"    , 0, 0, 0},
  116.     {NM_END,        NULL,                    0        , 0, 0, 0}
  117. };
  118.  
  119. struct TextAttr        Topaz80 =
  120. {
  121.     "topaz.font",
  122.     8,
  123.     0,
  124.     0
  125. };
  126.  
  127. struct NewBroker    NewBroker =
  128. {
  129.     NB_VERSION,                                /* nb_Version - Version of the NewBroker structure› */
  130.     PROG_NAME,                                /* nb_Name - Name Commodities uses to identify this commodity */
  131.     PROG_NAME,                                /* nb_Title - Title of commodity that appears in CXExchange */
  132.     PROG_DESCR,                                /* nb_Descr - Description of the commodity */
  133.     NBU_UNIQUE | NBU_NOTIFY,    /* nb_Unique - Tells CX not to launch another commodity with same name */
  134.     COF_SHOW_HIDE,                        /* nb_Flags - Tells CX if this commodity has a window */
  135.     0,                                                /* nb_Pri - This commodity's priority */
  136.     0,                                                /* nb_Port - MsgPort CX talks to */
  137.     0                                                    /* nb_ReservedChannel - reserved for later use */
  138. };
  139.  
  140. struct ItemNode
  141. {
  142.     struct Node    node;
  143.     APTR                Item;
  144.     UBYTE                ItemName[80];
  145. };
  146.  
  147.  
  148. /**********************************************************/
  149. /*  Variables                                             */
  150. /**********************************************************/
  151.  
  152. /*---------*/
  153. /* Strings */
  154. /*---------*/
  155.  
  156. char                                    __stdiowin[]        = "CON:0/11/640/80/"
  157.                                                                                  PROG_NAME " " PROG_VERSION;
  158.  
  159. static const char            Version[]                = "\0$VER: " PROG_NAME " "
  160.                                                                                 PROG_VERSION " (" PROG_DATE ")\0";
  161. char                                      Title[80];
  162.  
  163. /*-----------*/
  164. /* Libraries */
  165. /*-----------*/
  166.  
  167. struct Library                 *IconBase                = NULL,
  168.                                             *CxBase                    = NULL,
  169.                                             *GadToolsBase        = NULL;
  170.  
  171. struct GfxBase                *GfxBase                = NULL;
  172. struct IntuitionBase    *IntuitionBase    = NULL;
  173.  
  174. /*---------*/
  175. /* Devices */
  176. /*---------*/
  177.  
  178. struct timerequest        *TimerIO                = NULL;
  179. struct MsgPort                *TimerMP                = NULL;
  180.  
  181. /*-------*/
  182. /* Lists */
  183. /*-------*/
  184.  
  185. struct ItemNode                *WorkNode, *NextNode;
  186. struct List                        *ItemList                = NULL;
  187.  
  188. /*--------------------------------*/
  189. /* Screens, Windows, Gadgets, ... */
  190. /*--------------------------------*/
  191.  
  192. struct Window                    *Win                        = NULL,
  193.                                             *NextWindow,
  194.                                             *ActiveWin;
  195. struct Screen                    *Scr                        = NULL,
  196.                                             *NextScreen;
  197. APTR                                     *VisualInfo         = NULL;
  198. struct Menu                     *MenuStrip            = NULL;
  199. struct Gadget                    *GList                    = NULL,
  200.                                             *ListViewGad;
  201. char                                    GadgetText[]        = "Screen & Window List";
  202. WORD                                    WinLeft                    = 100,
  203.                                             WinTop                    = 50,
  204.                                             WinHeight,
  205.                                             WinWidth;
  206.  
  207. /*-------------*/
  208. /* Commodities */
  209. /*-------------*/
  210.  
  211. CxObj                                    *Broker                    = NULL;
  212. CxMsg                                    *BrokerMsg            = NULL;
  213. struct MsgPort                *BrokerMP                = NULL;
  214.  
  215. /*------*/
  216. /* Misc */
  217. /*------*/
  218.  
  219. int                                     ReturnCode            = RETURN_OK;
  220. LONG                                    DevError                = -1,
  221.                                             OptPriority            = 0;
  222. UWORD                                    NumLabels,
  223.                                             SelectedLabel        = 0;
  224. char                                    OptHotKey[40]        = DEF_HOTKEY,
  225.                                             OptPubScreen[40]= DEF_PUBSCREEN;
  226. BOOL                                    OptPopup                = TRUE,
  227.                                             CxActive,
  228.                                             Interface                = FALSE,
  229.                                             RequestSent            = FALSE;
  230.  
  231.  
  232. /**********************************************************/
  233. /*  main                                                  */
  234. /**********************************************************/
  235.  
  236. int main (int argc, char *argv[])
  237. {
  238.     if (open_libs())
  239.     {
  240.         if (read_args(argc, argv))
  241.         {
  242.             if (open_device())
  243.             {
  244.                 if (setup_cx())
  245.                 {
  246.                     if (OptPopup)
  247.                         open_interface();
  248.  
  249.                     if ((OptPopup && Interface) || (! OptPopup))
  250.                         process_msg();
  251.                 }
  252.             }
  253.         }
  254.     }
  255.     close_interface();
  256.     free_cx();
  257.     close_device();
  258.     close_libs();
  259.  
  260.     return(ReturnCode);
  261. }
  262.  
  263. /**********************************************************/
  264. /*  open_libs                                             */
  265. /**********************************************************/
  266.  
  267. BOOL open_libs(void)
  268. {
  269.     if ((CxBase = OpenLibrary("commodities.library", 37)) != NULL)
  270.     {
  271.         if ((GadToolsBase = OpenLibrary("gadtools.library", 37)) != NULL)
  272.         {
  273.             if ((IntuitionBase = (struct IntuitionBase *)OpenLibrary("intuition.library", 37)) != NULL)
  274.             {
  275.                 if ((GfxBase = (struct GfxBase *)OpenLibrary("graphics.library", 37)) != NULL)
  276.                 {
  277.                     if ((IconBase = OpenLibrary("icon.library", 37)) != NULL)
  278.                     {
  279.                         return(TRUE);
  280.                     }
  281.                 }
  282.             }
  283.         }
  284.     }
  285.  
  286.     PrintFault(ERROR_INVALID_RESIDENT_LIBRARY, NULL);
  287.     ReturnCode = RETURN_FAIL;
  288.  
  289.     return(FALSE);
  290. }
  291.  
  292. /**********************************************************/
  293. /*  close_libs                                            */
  294. /**********************************************************/
  295.  
  296. void close_libs(void)
  297. {
  298.     if (CxBase                != NULL)    CloseLibrary(CxBase);
  299.     if (GadToolsBase    != NULL)    CloseLibrary(GadToolsBase);
  300.     if (IntuitionBase    != NULL)    CloseLibrary((struct Library *)IntuitionBase);
  301.     if (GfxBase                != NULL)    CloseLibrary((struct Library *)GfxBase);
  302.     if (IconBase            != NULL)    CloseLibrary(IconBase);
  303. }
  304.  
  305. /**********************************************************/
  306. /*  read_args                                             */
  307. /**********************************************************/
  308.  
  309. BOOL read_args(int argc, char *argv[])
  310. {
  311.     struct WBStartup    *WBenchMsg;
  312.     struct WBArg            *WBenchArg;
  313.  
  314.     struct DiskObject *DiskObj;
  315.     char                            **ToolArray, *ToolValue;
  316.  
  317.     struct RDArgs            *RDA;
  318.     LONG                            OptArray[NUM_OPTS], Error, OldDir;
  319.  
  320.     char                            No[]    = "NO";
  321.  
  322.     /* Set default values */
  323.  
  324.     OptArray[OPT_POPUP]            = (LONG)"YES";
  325.     OptArray[OPT_HOTKEY]        = NULL;
  326.     OptArray[OPT_PRIORITY]    = 0;
  327.     OptArray[OPT_PUBSCREEN]    =    NULL;
  328.  
  329.     if (argc == 0)
  330.     {
  331.         /* The program was started from the Workbench */
  332.  
  333.         WBenchMsg         = (struct WBStartup *)argv;
  334.         WBenchArg            = WBenchMsg->sm_ArgList;
  335.  
  336.         /* Process only the first argument (our tool). Ignore */
  337.         /* any additional args which are icons passed to us   */
  338.         /* via either extend select or default tool method.   */
  339.  
  340.         if (WBenchArg->wa_Name != NULL)
  341.         {
  342.             /* Change to the directory where the file is stored */
  343.  
  344.             if (WBenchArg->wa_Lock != NULL)
  345.             {
  346.                 OldDir = CurrentDir(WBenchArg->wa_Lock);
  347.             }
  348.             else
  349.                 OldDir = -1;
  350.  
  351.             /* Read DiskObject structure (.info file) */
  352.  
  353.             if ((DiskObj = GetDiskObject(WBenchArg->wa_Name)) != NULL)
  354.             {
  355.                 /* Get the pointer to the ToolType array */
  356.  
  357.                 ToolArray = DiskObj->do_ToolTypes;
  358.  
  359.                 /* Check for ToolTypes we need and get the */
  360.                 /* value(s) of the ToolTypes.              */
  361.  
  362.                 if ((ToolValue = FindToolType(ToolArray, "CX_POPUP")) != NULL)
  363.                     if (MatchToolValue(ToolValue, No))
  364.                         OptPopup = FALSE;
  365.  
  366.                 if ((ToolValue = FindToolType(ToolArray, "CX_POPKEY")) != NULL)
  367.                     if (strlen(ToolValue) < 40)
  368.                         strcpy(OptHotKey, ToolValue);
  369.  
  370.                 if ((ToolValue = FindToolType(ToolArray, "CX_PRIORITY")) != NULL)
  371.                     OptPriority = atol(ToolValue);
  372.  
  373.                 if ((ToolValue = FindToolType(ToolArray, "PUBSCREEN")) != NULL)
  374.                     if (strlen(ToolValue) < 40)
  375.                         strcpy(OptPubScreen, ToolValue);
  376.  
  377.                 FreeDiskObject(DiskObj);
  378.             }
  379.  
  380.             /* Change back to the original directory */
  381.  
  382.             if (OldDir != -1)
  383.                 CurrentDir(OldDir);
  384.         }
  385.     }
  386.     else
  387.     {
  388.         /* The program was started from the Shell */
  389.  
  390.         if ((RDA = ReadArgs(TEMPLATE, OptArray, NULL)))
  391.         {
  392.             /* The user typed a valid command line */
  393.  
  394.             if (stricmp((char *)OptArray[OPT_POPUP], No) == NULL)
  395.                 OptPopup = FALSE;
  396.  
  397.             if (OptArray[OPT_HOTKEY] != NULL)
  398.                 if (strlen((char *)OptArray[OPT_HOTKEY]) < 40)
  399.                     strcpy(OptHotKey, (char *)OptArray[OPT_HOTKEY]);
  400.             
  401.             if (OptArray[OPT_PUBSCREEN] != NULL)
  402.                 if (strlen((char *)OptArray[OPT_PUBSCREEN]) < 40)
  403.                     strcpy(OptPubScreen, (char *)OptArray[OPT_PUBSCREEN]);
  404.  
  405.             OptPriority = OptArray[OPT_PRIORITY];
  406.  
  407.             FreeArgs(RDA);
  408.         }
  409.         else
  410.         {
  411.             /* There is an error in the command line */
  412.  
  413.             Error = IoErr();
  414.             PrintFault(Error, argv[0]);
  415.             ReturnCode = RETURN_FAIL;
  416.  
  417.             return(FALSE);
  418.         }
  419.     }
  420.  
  421.     return(TRUE);
  422. }
  423.  
  424. /**********************************************************/
  425. /*  open_device                                           */
  426. /**********************************************************/
  427.  
  428. BOOL open_device(void)
  429. {
  430.     if (ItemList = AllocMem(sizeof(struct List), MEMF_PUBLIC | MEMF_CLEAR))
  431.     {
  432.         NewList(ItemList);
  433.         if (TimerMP = CreateMsgPort())
  434.         {
  435.             if (TimerIO = (struct timerequest *)CreateIORequest(TimerMP, sizeof(struct timerequest)))
  436.             {
  437.                 if ((DevError = OpenDevice("timer.device", UNIT_VBLANK, (struct IORequest *)TimerIO, 0)) == 0)
  438.                 {
  439.                     return(TRUE);
  440.                 }
  441.             }
  442.         }
  443.     }
  444.  
  445.     ReturnCode = RETURN_FAIL;
  446.  
  447.     return(FALSE);
  448. }
  449.  
  450. /**********************************************************/
  451. /*  close_device                                          */
  452. /**********************************************************/
  453.  
  454. void close_device(void)
  455. {
  456.     if (RequestSent)
  457.     {
  458.         if (CheckIO((struct IORequest *)TimerIO) == NULL)
  459.         {
  460.           AbortIO((struct IORequest *)TimerIO);
  461.         }
  462.         WaitIO((struct IORequest *)TimerIO);
  463.     }
  464.  
  465.     if (DevError    != -1)        CloseDevice((struct IORequest *)TimerIO);
  466.     if (TimerIO         != NULL)    DeleteIORequest(TimerIO);
  467.     if (TimerMP         != NULL)    DeleteMsgPort(TimerMP);
  468.  
  469.     if (ItemList != NULL)
  470.     {
  471.         free_nodes();
  472.         if (ItemList     != NULL)    FreeMem(ItemList, sizeof(struct List));
  473.     }
  474. }
  475.  
  476. /**********************************************************/
  477. /*  setup_cx                                              */
  478. /**********************************************************/
  479.  
  480. BOOL setup_cx(void)
  481. {
  482.     CxObj *Filter, *Sender, *Translate;
  483.  
  484.     if ((BrokerMP = CreateMsgPort()))
  485.     {
  486.         if (OptPriority < -128 || OptPriority > 127)
  487.             OptPriority = 0;
  488.  
  489.         NewBroker.nb_Pri    = OptPriority;
  490.         NewBroker.nb_Port    = BrokerMP;
  491.  
  492.         /* create the title of the cx window */
  493.         
  494.         sprintf(Title, "%s: Hot Key = <%s>", PROG_NAME, OptHotKey);
  495.  
  496.         if ((Broker = CxBroker(&NewBroker, NULL)))
  497.         {
  498.             if ((Filter = CxFilter(OptHotKey)))
  499.             {
  500.                 AttachCxObj(Broker, Filter);
  501.                 if ((Sender = CxSender(BrokerMP, EVT_HOTKEY)))
  502.                 {
  503.                     AttachCxObj(Filter, Sender);
  504.                     if ((Translate = CxTranslate(NULL)))
  505.                     {
  506.                         AttachCxObj(Filter, Translate);
  507.                         if (CxObjError(Filter) == NULL)
  508.                         {
  509.                             ActivateCxObj(Broker, 1);
  510.                             CxActive = TRUE;
  511.                             return(TRUE);
  512.                         }
  513.                     }
  514.                 }
  515.             }
  516.         }
  517.     }
  518.  
  519.     ReturnCode = RETURN_FAIL;
  520.  
  521.     return(FALSE);
  522. }
  523.  
  524. /**********************************************************/
  525. /*  free_cx                                               */
  526. /**********************************************************/
  527.  
  528. void free_cx(void)
  529. {
  530.     if (Broker != NULL)
  531.         DeleteCxObjAll(Broker);
  532.  
  533.     if (BrokerMP != NULL)
  534.     {
  535.         while ((BrokerMsg = (CxMsg *)GetMsg(BrokerMP)))
  536.             ReplyMsg((struct Message *)BrokerMsg);
  537.  
  538.         DeletePort(BrokerMP);
  539.     }
  540. }
  541.  
  542. /**********************************************************/
  543. /*  open_interface                                        */
  544. /**********************************************************/
  545.  
  546. BOOL open_interface(void)
  547. {
  548.     UWORD                            DispWidth, DispHeight;
  549.     ULONG                            ScreenModeID;
  550.     struct Rectangle    Rect;
  551.  
  552.     if (IntuitionBase->ActiveWindow != Win)
  553.         ActiveWin = IntuitionBase->ActiveWindow;
  554.     
  555.     if (Win == NULL)
  556.     {
  557.         if ((Scr = LockPubScreen(OptPubScreen)) == NULL)
  558.             Scr = LockPubScreen(DEF_PUBSCREEN);
  559.             
  560.         if (Scr)
  561.         {
  562.             if (VisualInfo = GetVisualInfo(Scr, TAG_END))
  563.             {
  564.                 if (gadgets())
  565.                 {
  566.                     if (menu())
  567.                     {
  568.                         if((ScreenModeID = GetVPModeID(&Scr->ViewPort)) != INVALID_ID)
  569.                         {
  570.                             if(QueryOverscan(ScreenModeID, &Rect, OSCAN_TEXT))
  571.                             {
  572.                                 DispWidth = Rect.MaxX - Rect.MinX + 1;
  573.                                 DispHeight = Rect.MaxY - Rect.MinY + 1;
  574.  
  575.                                 WinLeft = Scr->MouseX;
  576.                                 WinTop = Scr->MouseY;
  577.  
  578.                                 if (WinLeft < -Scr->LeftEdge)
  579.                                 {
  580.                                     WinLeft = max(0, -Scr->LeftEdge);
  581.                                     WinLeft = WinLeft + 100;
  582.                                 }
  583.  
  584.                                 if (WinTop < -Scr->TopEdge)
  585.                                 {
  586.                                     WinTop = max(0, -Scr->TopEdge);
  587.                                     WinTop = WinTop + 50;
  588.                                 }
  589.  
  590.                                 if ((WinLeft + WinWidth) > (DispWidth + -Scr->LeftEdge))
  591.                                 {
  592.                                     WinLeft = (DispWidth + -Scr->LeftEdge) - WinWidth;
  593.                                 }
  594.  
  595.                                 if ((WinTop + WinHeight) > (DispHeight + -Scr->TopEdge))
  596.                                 {
  597.                                     WinTop = (DispHeight + -Scr->TopEdge) - WinHeight;
  598.                                 }
  599.                             }
  600.                         }
  601.  
  602.                         if (Win = OpenWindowTags(NULL,
  603.                                 WA_PubScreen, Scr,
  604.                                 WA_Left, WinLeft,
  605.                                 WA_Top, WinTop,
  606.                                 WA_Height, WinHeight,
  607.                                 WA_Width, WinWidth,
  608.                                 WA_Gadgets, GList,
  609.                                 WA_Title, Title,
  610.                                 WA_IDCMP, WIN_IDCMP,
  611.                                 WA_Flags, WFLG_CLOSEGADGET | WFLG_DEPTHGADGET |
  612.                                                     WFLG_ACTIVATE | WFLG_DRAGBAR | WFLG_SMART_REFRESH,
  613.                                 TAG_DONE))
  614.                         {
  615.                             GT_RefreshWindow(Win, NULL);
  616.                             if(SetMenuStrip(Win, MenuStrip))
  617.                             {
  618.                                 WindowToFront(Win);
  619.                                 ScreenToFront(Win->WScreen);
  620.                                 Interface = TRUE;
  621.                                 refresh_listview();
  622.                                 return(TRUE);
  623.                             }
  624.                         }
  625.                     }
  626.                 }
  627.             }
  628.         }
  629.         close_interface();
  630.         return(FALSE);
  631.     }
  632.     else
  633.     {
  634.         WindowToFront(Win);
  635.         ActivateWindow(Win);
  636.         ScreenToFront(Win->WScreen);
  637.         refresh_listview();
  638.         return(TRUE);
  639.     }
  640. }
  641.  
  642.  
  643. /**********************************************************/
  644. /*  close_interface                                       */
  645. /**********************************************************/
  646.  
  647. void close_interface(void)
  648. {
  649.     if(Win != NULL)
  650.     {
  651.         ClearMenuStrip(Win);
  652.         CloseWindow(Win);
  653.         Win = NULL;
  654.     }
  655.  
  656.     if (MenuStrip != NULL)
  657.     {
  658.         FreeMenus(MenuStrip);
  659.         MenuStrip = NULL;
  660.     }
  661.  
  662.     if (GList != NULL)
  663.     {
  664.         FreeGadgets(GList);
  665.         GList = NULL;
  666.     }
  667.  
  668.     if (VisualInfo != NULL)
  669.     {
  670.         FreeVisualInfo(VisualInfo);
  671.         VisualInfo = NULL;
  672.     }
  673.  
  674.     if (Scr != NULL)
  675.     {
  676.         UnlockPubScreen(NULL, Scr);
  677.         Scr = NULL;
  678.     }
  679.  
  680.     Interface = FALSE;
  681. }
  682.  
  683. /**********************************************************/
  684. /*  gadgets                                               */
  685. /**********************************************************/
  686.  
  687. BOOL gadgets(void)
  688. {
  689.     WORD                    PixLength;
  690.     struct Gadget *Gad;
  691.     
  692.     PixLength = TextLength(&Scr->RastPort, GadgetText, strlen(GadgetText));
  693.  
  694.     /* Listview gadget */
  695.  
  696.     ng.ng_LeftEdge        = 16;
  697.     ng.ng_TopEdge            = Scr->WBorTop + (Scr->Font->ta_YSize * 2 + INTERHEIGHT * 2);
  698.     ng.ng_Width                = PixLength * 2;
  699.     ng.ng_Height            = Scr->Font->ta_YSize * 16;
  700.     ng.ng_GadgetText    = GadgetText;
  701.     ng.ng_TextAttr        = Scr->Font;
  702.     ng.ng_GadgetID        = ID_LISTVIEW;
  703.     ng.ng_Flags                = 0;
  704.     ng.ng_UserData        = NULL;
  705.     ng.ng_VisualInfo    = VisualInfo;
  706.  
  707.     Gad = CreateContext(&GList);
  708.     Gad = ListViewGad = CreateGadget(LISTVIEW_KIND, Gad, &ng,
  709.                                                                      GTLV_Labels, NULL,
  710.                                                                      GTLV_ShowSelected, NULL,
  711.                                                                      GTLV_Selected, 0,
  712.                                                                      TAG_END);
  713.  
  714.     if (Gad != NULL)
  715.     {
  716.         WinHeight = ng.ng_TopEdge + Gad->Height + INTERHEIGHT * 2;
  717.         WinWidth  = ng.ng_LeftEdge + Gad->Width + INTERWIDTH * 2;
  718.         return(TRUE);
  719.     }
  720.     else
  721.         return(FALSE);
  722. }
  723.  
  724. /**********************************************************/
  725. /*  menu                                                  */
  726. /**********************************************************/
  727.  
  728. BOOL menu(void)
  729. {
  730.     if ((MenuStrip = CreateMenus(NewMenu, TAG_END)))
  731.     {
  732.         if (LayoutMenus(MenuStrip, VisualInfo, TAG_END))
  733.         {
  734.             return(TRUE);
  735.         }
  736.     }
  737.  
  738.     return(FALSE);
  739. }
  740.  
  741. /**********************************************************/
  742. /*  refresh_listview                                      */
  743. /**********************************************************/
  744.  
  745. void refresh_listview(void)
  746. {
  747.     GT_SetGadgetAttrs(ListViewGad, Win, NULL,
  748.                                         GTLV_Labels, ~0,
  749.                                         TAG_END);
  750.  
  751.     if (create_item_list())
  752.     {
  753.         GT_SetGadgetAttrs(ListViewGad, Win, NULL,
  754.                                             GTLV_Labels, ItemList,
  755.                                             TAG_END);
  756.                                             
  757.         if (SelectedLabel > (NumLabels - 1))
  758.             SelectedLabel = NumLabels - 1;
  759.         
  760.         GT_SetGadgetAttrs(ListViewGad, Win, NULL,
  761.                                             GTLV_Selected, SelectedLabel,
  762.                                             TAG_END);
  763.     }
  764. }
  765.  
  766. /**********************************************************/
  767. /*  create_item_list                                      */
  768. /**********************************************************/
  769.  
  770. BOOL create_item_list(void)
  771. {
  772.     free_nodes();
  773.     NumLabels = 0;
  774.  
  775.     if ((WorkNode = AllocMem(sizeof(struct ItemNode), MEMF_PUBLIC | MEMF_CLEAR)))
  776.     {
  777.         WorkNode->node.ln_Pri        = PRI_TITLE_SCREENS;
  778.         WorkNode->node.ln_Type    = NT_USER;
  779.         WorkNode->Item                    = NULL;
  780.  
  781.         strcpy(WorkNode->ItemName, "(Screens)");
  782.         WorkNode->node.ln_Name    = WorkNode->ItemName;
  783.  
  784.         Enqueue(ItemList, (struct Node *)WorkNode);
  785.         NumLabels++;
  786.  
  787.         if ((WorkNode = AllocMem(sizeof(struct ItemNode), MEMF_PUBLIC | MEMF_CLEAR)))
  788.         {
  789.             WorkNode->node.ln_Pri        = PRI_TITLE_WINDOWS;
  790.             WorkNode->node.ln_Type    = NT_USER;
  791.             WorkNode->Item                    = NULL;
  792.  
  793.             strcpy(WorkNode->ItemName, "(Windows)");
  794.             WorkNode->node.ln_Name    = WorkNode->ItemName;
  795.  
  796.             Enqueue(ItemList, (struct Node *)WorkNode);
  797.             NumLabels++;
  798.  
  799.             if (IntuitionBase->FirstScreen != NULL)
  800.             {
  801.                 NextScreen = IntuitionBase->FirstScreen;
  802.  
  803.                 while (NextScreen != NULL)
  804.                 {
  805.                     if ((WorkNode = AllocMem(sizeof(struct ItemNode), MEMF_PUBLIC | MEMF_CLEAR)))
  806.                     {
  807.                         WorkNode->node.ln_Pri        = PRI_SCREENS;
  808.                         WorkNode->node.ln_Type    = NT_USER;
  809.                         WorkNode->Item                    = NextScreen;
  810.  
  811.                         strcpy(WorkNode->ItemName, "  ");
  812.  
  813.                         if (NextScreen->Title != NULL)
  814.                             strncat(WorkNode->ItemName, NextScreen->Title, 77);
  815.                         else
  816.                             strcat(WorkNode->ItemName, "<no title>");
  817.  
  818.                         WorkNode->node.ln_Name    = WorkNode->ItemName;
  819.  
  820.                         Enqueue(ItemList, (struct Node *)WorkNode);
  821.                         NumLabels++;
  822.  
  823.                         if (NextScreen->FirstWindow != NULL)
  824.                         {
  825.                             NextWindow = NextScreen->FirstWindow;
  826.  
  827.                             while (NextWindow != NULL)
  828.                             {
  829.                                 if ((WorkNode = AllocMem(sizeof(struct ItemNode), MEMF_PUBLIC | MEMF_CLEAR)))
  830.                                 {
  831.                                     WorkNode->node.ln_Pri     = PRI_WINDOWS;
  832.                                     WorkNode->node.ln_Type = NT_USER;
  833.                                     WorkNode->Item                 = NextWindow;
  834.  
  835.                                     if (NextWindow != ActiveWin)
  836.                                         strcpy(WorkNode->ItemName, "  ");
  837.                                     else
  838.                                         strcpy(WorkNode->ItemName, "> ");
  839.  
  840.                                     if (NextWindow->Title != NULL)
  841.                                         strncat(WorkNode->ItemName, NextWindow->Title, 77);
  842.                                     else
  843.                                         strcat(WorkNode->ItemName, "<no title>");
  844.  
  845.                                     WorkNode->node.ln_Name = WorkNode->ItemName;
  846.  
  847.                                     Enqueue(ItemList, (struct Node *)WorkNode);
  848.                                     NumLabels++;
  849.  
  850.                                     NextWindow = NextWindow->NextWindow;
  851.                                 }
  852.                                 else
  853.                                     return(FALSE);
  854.                             }
  855.                         }
  856.                         NextScreen = NextScreen->NextScreen;
  857.                     }
  858.                     else
  859.                         return(FALSE);
  860.                 }
  861.             }
  862.         }
  863.         else
  864.             return(FALSE);
  865.     }
  866.     else
  867.         return(FALSE);
  868.  
  869.     return(TRUE);
  870. }
  871.  
  872.  
  873. /**********************************************************/
  874. /*  free_nodes                                            */
  875. /**********************************************************/
  876.  
  877. void free_nodes(void)
  878. {
  879.     WorkNode = (struct ItemNode *)ItemList->lh_Head;
  880.  
  881.     while ((NextNode = (struct ItemNode *)WorkNode->node.ln_Succ))
  882.     {
  883.         Remove((struct Node *)WorkNode);
  884.         FreeMem(WorkNode, sizeof(struct ItemNode));
  885.         WorkNode = NextNode;
  886.     }
  887. }
  888.  
  889. /**********************************************************/
  890. /*  newshell                                              */
  891. /**********************************************************/
  892.  
  893. void newshell(void)
  894. {
  895.     Execute("Newshell", NULL, NULL);
  896. }
  897.  
  898. /**********************************************************/
  899. /*  timer                                                 */
  900. /**********************************************************/
  901.  
  902. void timer(void)
  903. {
  904.     if (CxActive && Interface)
  905.     {
  906.         TimerIO->tr_node.io_Command    = TR_ADDREQUEST;
  907.         TimerIO->tr_time.tv_secs        = 1;
  908.         TimerIO->tr_time.tv_micro        = 0;
  909.  
  910.         SendIO((struct IORequest *)TimerIO);
  911.  
  912.         RequestSent = TRUE;
  913.     }
  914. }
  915.  
  916. /**********************************************************/
  917. /*  click_to_front                                        */
  918. /**********************************************************/
  919.  
  920. void click_to_front(UWORD ItemNumber)
  921. {
  922.     WorkNode = (struct ItemNode *)ItemList->lh_Head;
  923.  
  924.     for (ItemNumber; ItemNumber > 0; ItemNumber--)
  925.         WorkNode = (struct ItemNode *)WorkNode->node.ln_Succ;
  926.  
  927.     switch (WorkNode->node.ln_Pri)
  928.     {
  929.         case PRI_WINDOWS:
  930.             ScreenToFront(((struct Window *)WorkNode->Item)->WScreen);
  931.             WindowToFront((struct Window *)WorkNode->Item);
  932.             ActivateWindow((struct Window *)WorkNode->Item);
  933.             Interface = FALSE;
  934.             break;
  935.  
  936.         case PRI_SCREENS:
  937.             ScreenToFront((struct Screen *)WorkNode->Item);
  938.             if (((struct Screen *)WorkNode->Item)->FirstWindow != NULL)
  939.             {
  940.                 WindowToFront(((struct Screen *)WorkNode->Item)->FirstWindow);
  941.                 ActivateWindow(((struct Screen *)WorkNode->Item)->FirstWindow);
  942.             }
  943.             Interface = FALSE;
  944.             break;
  945.  
  946.         default:
  947.             break;
  948.     }
  949. }
  950.  
  951. /**********************************************************/
  952. /*  select_label                                          */
  953. /**********************************************************/
  954.  
  955. void select_label(void)
  956. {
  957.     if (Interface)
  958.         GT_SetGadgetAttrs(ListViewGad, Win, NULL,
  959.                                             GTLV_Selected, SelectedLabel,
  960.                                             GTLV_MakeVisible, SelectedLabel,
  961.                                             TAG_END);
  962. }
  963.  
  964. /**********************************************************/
  965. /*  about                                                 */
  966. /**********************************************************/
  967.  
  968. void about(void)
  969. {
  970.     struct EasyStruct Req =
  971.     {
  972.         sizeof(struct EasyStruct),
  973.         0,
  974.         "About",
  975.         "%s\n\nVersion %s (%s)\n\nAuthor: Torsten Kramer\neMail: torstenk@enterp.gun.de\n\nThis program is freeware.\nCopyright 1995 by Torsten Kramer.",
  976.         "OK"
  977.     };
  978.     
  979.     EasyRequest(Win, &Req, NULL, PROG_NAME, PROG_VERSION, PROG_DATE);
  980. }
  981.  
  982. /**********************************************************/
  983. /*  process_msg                                           */
  984. /**********************************************************/
  985.  
  986. void process_msg(void)
  987. {
  988.     struct IntuiMessage    *IMsg;
  989.  
  990.     APTR        IAdr;
  991.     ULONG        MsgClass, MsgID, MsgType,
  992.                     CxSigFlag, WinSigFlag, TimerSigFlag,
  993.                     Signals, SigReceived;
  994.     UWORD        Code;
  995.     BOOL        Done = TRUE;
  996.     
  997.     CxSigFlag            = 1L << BrokerMP->mp_SigBit;
  998.     TimerSigFlag    = 1L << TimerMP->mp_SigBit;
  999.  
  1000.     while (Done)
  1001.     {
  1002.         if (Interface)
  1003.         {
  1004.             WinSigFlag    = 1L << Win->UserPort->mp_SigBit;
  1005.             Signals            = SIGBREAKF_CTRL_C | CxSigFlag | TimerSigFlag | WinSigFlag;
  1006.         }
  1007.         else
  1008.         {
  1009.             close_interface();
  1010.             Signals            = SIGBREAKF_CTRL_C | CxSigFlag | TimerSigFlag;
  1011.         }
  1012.  
  1013.         if (RequestSent == FALSE)
  1014.             timer();
  1015.  
  1016.         SigReceived = Wait(Signals);
  1017.  
  1018.         if (SigReceived & TimerSigFlag)
  1019.         {
  1020.             /* Cleanup the port */
  1021.  
  1022.             WaitIO((struct IORequest *)TimerIO);
  1023.  
  1024.             RequestSent = FALSE;
  1025.  
  1026.             if(Interface)
  1027.                 refresh_listview();
  1028.         }
  1029.  
  1030.         if (SigReceived & WinSigFlag)
  1031.         {
  1032.             while (IMsg = GT_GetIMsg(Win->UserPort))
  1033.             {
  1034.                 Code            = IMsg->Code;
  1035.                 MsgClass    = IMsg->Class;
  1036.                 IAdr            = IMsg->IAddress;
  1037.  
  1038.                 GT_ReplyIMsg(IMsg);
  1039.  
  1040.                 switch (MsgClass)
  1041.                 {
  1042.                     case IDCMP_CLOSEWINDOW:
  1043.                         Interface = FALSE;
  1044.                         break;
  1045.  
  1046.                     case IDCMP_MENUPICK:
  1047.                         if (Code != MENUNULL)
  1048.                         {
  1049.                             switch (MENUNUM(Code))
  1050.                             {
  1051.                                 case MENU_PROJECT:
  1052.                                     switch (ITEMNUM(Code))
  1053.                                     {
  1054.                                         case ITEM_HIDE:
  1055.                                             Interface = FALSE;
  1056.                                             break;
  1057.  
  1058.                                         case ITEM_NEWSHELL:
  1059.                                             newshell();
  1060.                                             Interface = FALSE;
  1061.                                             break;
  1062.                                         
  1063.                                         case ITEM_ABOUT:
  1064.                                             about();
  1065.                                             break;
  1066.  
  1067.                                         case ITEM_QUIT:
  1068.                                             Done = FALSE;
  1069.                                             break;
  1070.  
  1071.                                         default:
  1072.                                             break;
  1073.                                     }
  1074.                                     break;
  1075.  
  1076.                                 default:
  1077.                                     break;
  1078.                             }
  1079.                         }
  1080.                         break;
  1081.  
  1082.                     case IDCMP_GADGETUP:
  1083.                         switch (((struct Gadget *)IAdr)->GadgetID)
  1084.                         {
  1085.                             case ID_LISTVIEW:
  1086.                                 click_to_front(Code);
  1087.                                 SelectedLabel = Code;
  1088.                                 break;
  1089.  
  1090.                             default:
  1091.                                 break;
  1092.                         }
  1093.                         break;
  1094.                     
  1095.                     case IDCMP_RAWKEY:
  1096.                         switch (Code)
  1097.                         {
  1098.                             case CURSOR_UP:
  1099.                                 if (SelectedLabel > 0)
  1100.                                     SelectedLabel--;
  1101.                                 
  1102.                                 select_label();
  1103.                                 break;
  1104.                             
  1105.                             case CURSOR_DOWN:
  1106.                                 if (SelectedLabel < (NumLabels - 1))
  1107.                                     SelectedLabel++;
  1108.                                 
  1109.                                 select_label();
  1110.                                 break;
  1111.                             
  1112.                             default:
  1113.                                 break;
  1114.                         }
  1115.                         break;
  1116.  
  1117.                     case IDCMP_VANILLAKEY:
  1118.                         switch (Code)
  1119.                         {
  1120.                             case ESC:
  1121.                                 Interface = FALSE;
  1122.                                 break;
  1123.                                 
  1124.                             case ENTER:
  1125.                                 click_to_front(SelectedLabel);
  1126.                                 break;
  1127.  
  1128.                             default:
  1129.                                 break;
  1130.  
  1131.                         }
  1132.                         break;
  1133.  
  1134.                     case IDCMP_REFRESHWINDOW:
  1135.                         GT_BeginRefresh(Win);
  1136.                         GT_EndRefresh(Win, TRUE);
  1137.                         break;
  1138.  
  1139.                     default:
  1140.                         break;
  1141.                 }
  1142.             }
  1143.         }
  1144.  
  1145.         if (SigReceived & CxSigFlag)
  1146.         {
  1147.             while ((BrokerMsg = (CxMsg *)GetMsg(BrokerMP)))
  1148.             {
  1149.                 MsgID        = CxMsgID(BrokerMsg);
  1150.                 MsgType    = CxMsgType(BrokerMsg);
  1151.  
  1152.                 ReplyMsg((struct Message *)BrokerMsg);
  1153.  
  1154.                 switch (MsgType)
  1155.                 {
  1156.                     case CXM_IEVENT:
  1157.                         switch (MsgID)
  1158.                         {
  1159.                             case EVT_HOTKEY:
  1160.                                 open_interface();
  1161.                                 
  1162.                                 if (Win != NULL)
  1163.                                 {
  1164.                                     WindowToFront(Win);
  1165.                                     ActivateWindow(Win);
  1166.                                     ScreenToFront(Win->WScreen);
  1167.                                 }
  1168.                                 break;
  1169.  
  1170.                             default:
  1171.                                 break;
  1172.                         }
  1173.                         break;
  1174.  
  1175.                     case CXM_COMMAND:
  1176.  
  1177.                         /* Commodities has sent a command */
  1178.  
  1179.                         switch (MsgID)
  1180.                         {
  1181.                             case CXCMD_DISABLE:
  1182.  
  1183.                                 /* The user clicked the Commodities Exchange */
  1184.                                 /* disable gadget.                           */
  1185.  
  1186.                                 ActivateCxObj(Broker, 0);
  1187.                                 CxActive = FALSE;
  1188.                                 break;
  1189.  
  1190.                             case CXCMD_ENABLE:
  1191.  
  1192.                                 /* The user clicked the Commodities Exchange */
  1193.                                 /* enable gadget.                            */
  1194.  
  1195.                                 ActivateCxObj(Broker, 1);
  1196.                                 CxActive = TRUE;
  1197.                                 break;
  1198.  
  1199.                             case CXCMD_KILL:
  1200.  
  1201.                                 /* The user clicked the Commodities Exchange */
  1202.                                 /* kill gadget.                              */
  1203.  
  1204.                                 Done = FALSE;
  1205.                                 break;
  1206.  
  1207.                             case CXCMD_APPEAR:
  1208.  
  1209.                                 /* The user clicked the Commodities Exchange */
  1210.                                 /* 'Show Interface' gadget.                  */
  1211.  
  1212.                                 open_interface();
  1213.                                 
  1214.                                 if (Win != NULL)
  1215.                                 {
  1216.                                     WindowToFront(Win);
  1217.                                     ActivateWindow(Win);
  1218.                                     ScreenToFront(Win->WScreen);
  1219.                                 }
  1220.                                 break;
  1221.  
  1222.                             case CXCMD_DISAPPEAR:
  1223.  
  1224.                                 /* The user clicked the Commodities Exchange */
  1225.                                 /* 'Hide Interface' gadget                   */
  1226.  
  1227.                                 Interface = FALSE;
  1228.                                 break;
  1229.  
  1230.                             case CXCMD_UNIQUE:
  1231.  
  1232.                                 /* The user started our Commodity twice */
  1233.  
  1234.                                 open_interface();
  1235.                                 
  1236.                                 if (Win != NULL)
  1237.                                 {
  1238.                                     WindowToFront(Win);
  1239.                                     ActivateWindow(Win);
  1240.                                     ScreenToFront(Win->WScreen);
  1241.                                 }
  1242.                                 break;
  1243.  
  1244.                             default:
  1245.                                 break;
  1246.                         }
  1247.               break;
  1248.  
  1249.                     default:
  1250.                         break;
  1251.           }
  1252.             }
  1253.         }
  1254.  
  1255.         if (SigReceived & SIGBREAKF_CTRL_C)
  1256.         {
  1257.             Done = FALSE;
  1258.         }
  1259.     }
  1260. }
  1261.